package com.faxsun.controller.uc;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.common.util.TransactionUtils;
import org.broadleafcommerce.common.web.controller.BroadleafAbstractController;
import org.broadleafcommerce.profile.core.domain.Customer;
import org.broadleafcommerce.profile.web.core.CustomerState;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.faxsun.controller.uc.entity.ThirdPartyLoginServer;
import com.faxsun.profile.core.exception.AccountBindedThirdAccountException;
import com.faxsun.profile.core.exception.ThirdAccountBindToMultipleAccountException;
import com.faxsun.profile.core.exception.ThirdAccountBindedException;
import com.faxsun.profile.core.service.FSThirdPartyCustomerService;
import com.faxsun.web.notification.FaxsunInfoNotfier;
import com.faxsun.web.notification.exception.FaxsunInfoBindFailException;
import com.faxsun.web.notification.exception.SessionTimeoutExceptiont;
import com.google.code.yanf4j.core.Session;

@Controller
@RequestMapping("/uc")
public class ProcessController extends BroadleafAbstractController {

	private static final Log LOG = LogFactory.getLog(ProcessController.class);

	@Resource(name = "fsThirdPartyService")
	ThirdPartyLoginServer login3rdService;

	@Resource(name = "blThirdPartyCustomerService")
	FSThirdPartyCustomerService fsThirdPartyCustomerService;

	@Resource(name = "fsInfoNotifier")
	FaxsunInfoNotfier faxsunInfoNotifier;

	/*** For K360， 涉及第三方修改接口，故保留 ***/
	@RequestMapping(value = "/third-party-login", method = RequestMethod.POST)
	public String thirdPartyLogin(HttpServletRequest request, HttpServletResponse response) {
		String path = null;
		return login3rdService.handle(request, response, path, "");
	}

	@RequestMapping(value = "/treasure", method = RequestMethod.POST)
	public String treasureLogin(HttpServletRequest request, HttpServletResponse response) {
		String path = "treasure";
		return login3rdService.handle(request, response, path, "");
	}
	/*** For K360 END ***/

	/*** Handle 3rd party login request ***/
	@RequestMapping(value = "/thirdparty/{channelId}", method = RequestMethod.GET)
	public String thirdPartyLogin(HttpServletRequest request, HttpServletResponse response,
			@PathVariable("channelId") String channelId) {
		String path = null;
		return login3rdService.handle(request, response, path, channelId);
	}

	/***
	 * Handle 3rd party login button request from Web Page. Used to create
	 * "code".
	 ***/
	@RequestMapping(value = "/thirdRequest", method = RequestMethod.GET)
	public void thirdPartyRequest(HttpServletRequest request, HttpServletResponse response) {
		login3rdService.requestURL(request, response);
	}

	/**
	 * 第三方帐户绑定请求，交由service处理
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/thirdbindrequest/{channelId}", method = RequestMethod.GET)
	public void thirdPartyBindRequest(@PathVariable("channelId") String channelId, HttpServletRequest request,
			HttpServletResponse response) {
		login3rdService.requestBindURL(channelId, request, response);
	}

	/**
	 * 执行绑定操作
	 * 
	 * @param request
	 * @param response
	 * @param channelId
	 * @return
	 */
	@RequestMapping(value = "/thirdparty/{channelId}/bind", method = RequestMethod.GET)
	public String thirdPartyBindUrl(HttpServletRequest request, HttpServletResponse response,
			@PathVariable("channelId") String channelId, ModelMap model) {

		String url = request.getParameter("redirect_uri");

		try {
			boolean isBindSuccess;

			isBindSuccess = login3rdService.processBind(channelId, request, response);
			if (isBindSuccess) {
				// 绑定成功，forward到accountUpdate
				return "redirect:" + url;
			} else {
				// TODO: 暂时使用空页面
				return "/account/bindFail";
			}
		} catch (ThirdAccountBindedException e) {
			LOG.error("", e);
			url = redirectToFailPage(url, response, e);
			model.addAttribute("exception", e);

		} catch (ThirdAccountBindToMultipleAccountException e) {
			LOG.error("", e);
			url = redirectToFailPage(url, response, e);
			model.addAttribute("exception", e);
		} catch (AccountBindedThirdAccountException e) {
			LOG.error("", e);
			url = redirectToFailPage(url, response, e);
			model.addAttribute("exception", e);
		} catch (FaxsunInfoBindFailException e) {
			url = redirectToFailPage(url, response, e);
			model.addAttribute("exception", e);
		} catch (SessionTimeoutExceptiont e) {
			LOG.error("", e);
			url = redirectToFailPage(url, response, e);
			model.addAttribute("exception", e);
		}
		if (StringUtils.isEmpty(url))
			return "/account/bindFail";
		else
			return "redirect:" + url;
	}

	/**
	 * 跳转到绑定失败页面
	 * 
	 * @param url
	 * @param response
	 * @param e
	 */
	private String redirectToFailPage(String url, HttpServletResponse response, Exception e) {
		String context = "";
		int indexOfProtocol = url.indexOf("://");
		int contextStartIndex = 0;
		int contextEndIndex = 0;

		if (indexOfProtocol >= 0) {
			contextStartIndex = url.indexOf("/", indexOfProtocol + 3) + 1;
			contextEndIndex = url.indexOf("/", contextStartIndex);
			if (contextStartIndex >= 0 && contextEndIndex >= 0) {
				context = url.substring(contextStartIndex, contextEndIndex);
			}
		} else {
			return "";
		}

		//从资讯过来的请求，跳转回资讯的展示页面
		if (context.equals("faxsun-info")) {

			URL uri;
			try {
				uri = new URL(url);
				String redirectUrl = uri.getProtocol() + "://" + uri.getHost() + "/" + context + "/bind/fail?code=";

				int errorCode = 0;
				if (e instanceof ThirdAccountBindedException) {
					errorCode = -1;
				} else if (e instanceof ThirdAccountBindToMultipleAccountException) {
					errorCode = -2;
				} else if (e instanceof AccountBindedThirdAccountException) {
					errorCode = -3;
				} else if (e instanceof SessionTimeoutExceptiont) {
					errorCode = -4;
				}
				return redirectUrl + errorCode;
			} catch (MalformedURLException e1) {
				LOG.error(e1);
			} catch (IOException e1) {
				LOG.error(e1);
			}

		}

		return "";
	}

	/**
	 * 第三方帐户解绑定请求
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/thirdunbindrequest/{channelId}", method = RequestMethod.GET)
	@ResponseBody
	@Transactional(TransactionUtils.DEFAULT_TRANSACTION_MANAGER)
	public String thirdPartyUnBindRequest(@PathVariable("channelId") String channelId, HttpServletRequest request,
			HttpServletResponse response) {
		Customer customer = CustomerState.getCustomer();

		if (customer != null && !customer.isAnonymous()) {

			boolean result = faxsunInfoNotifier.notifyUnbindAccount(customer.getId(), channelId);
			if (result) {

				fsThirdPartyCustomerService.unbind(customer.getId(), channelId);
				LOG.warn("Unbind Account Result=" + result + " customerId=" + customer.getId() + " channelId="
						+ channelId);
				return "true";
			} else {
				return "false";
			}

		}

		return "false";
	}
}
